﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedGenomics.Core.Collections;
using SharedGenomics.Annotations;
using SharedGenomics.Workbench.Annotations;

namespace SharedGenomics.Workbench.Tests.Annotations
{
    [TestClass]
    public class StaticAnnotationPlanTests
    {
        private StaticAnnotationPlan plan;

        [TestInitialize]
        public void Setup()
        {
            TreeNode<AnnotationKey> root = new TreeNode<AnnotationKey>(null);
            var googleNode = root.AddChild(AnnotationKey.GoogleSearch);
            var ncbiNode = root.AddChild(AnnotationKey.NcbiSummary);
            var tavernaNode = ncbiNode.AddChild(AnnotationKey.Taverna);
            var pubsNode = tavernaNode.AddChild(AnnotationKey.Publications);

            Tree<AnnotationKey> planTree = new Tree<AnnotationKey>() { Root = root };
            this.plan = new StaticAnnotationPlan(planTree);
        }

        [TestMethod]
        public void ShouldGetInitialRequestKeys()
        {
            var keys = this.plan.GetPendingRequests().ToArray();
            CollectionAssert.AreEqual(new[] { AnnotationKey.GoogleSearch, AnnotationKey.NcbiSummary }, keys);
        }

        [TestMethod]
        public void ShouldHaveNoInitialRequestKeys()
        {
            var planTree = new Tree<AnnotationKey>() { Root = new TreeNode<AnnotationKey>(null) };
            var plan = new StaticAnnotationPlan(planTree);

            Assert.AreEqual(0, plan.GetPendingRequests().Count());
        }

        [TestMethod]
        public void ShouldBeCompleteIfNoInitialRequests()
        {
            var planTree = new Tree<AnnotationKey>() { Root = new TreeNode<AnnotationKey>(null) };
            var plan = new StaticAnnotationPlan(planTree);

            Assert.IsTrue(plan.IsComplete);
        }

        [TestMethod]
        public void ShouldUnblockRequest()
        {
            var keys = this.plan.GetPendingRequests();

            //notify the plan the ncbi request has completed - this should unblock the taverna request
            plan.NotifyRequestFinished(AnnotationKey.NcbiSummary);
            var unblockedKeys = plan.GetPendingRequests();
            CollectionAssert.AreEqual(new[] { AnnotationKey.Taverna }, unblockedKeys.ToArray());
        }

        [TestMethod]
        public void ShouldNotifyRequestsAvailable()
        {
            var keys = this.plan.GetPendingRequests();

            //notify the plan the ncbi request has completed - this should unblock the taverna request
            bool eventRaised = false;
            plan.RequestsAvailable += (o, e) => { eventRaised = true; };

            plan.NotifyRequestFinished(AnnotationKey.NcbiSummary);

            Assert.IsTrue(eventRaised);
        }

        [TestMethod]
        public void ShouldNotifyFailedRequests()
        {
            var keys = this.plan.GetPendingRequests();

            //notify the ncbi request failed - this means the taverna and publications requests will also fail
            IList<AnnotationKey> failedKeys = null;
            plan.RequestsFailed += (o, e) => { failedKeys = e.FailedRequestKeys; };
            this.plan.NotifyRequestFailed(AnnotationKey.NcbiSummary);

            CollectionAssert.AreEqual(new[] { AnnotationKey.NcbiSummary, AnnotationKey.Taverna, AnnotationKey.Publications }, failedKeys.ToArray());
        }
    }
}
